<template>
  <div class="pie-box">
    <div v-if="showChart" ref="chart" style="width: 100%; height: 100%"></div>
    <nodata-box v-else></nodata-box>
    <div v-if="showChart" class="inner-circle"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts'
import { addZero } from '@/utils/util/format'

export default {
  name: 'PieChart',
  props: {
    data: {
      // NOTE: undefined表示数据仍在加载中
      type: Array,
      default: undefined
    },
    colors: {
      type: Array,
      default: () => {
        return [
          '#EE7777',
          '#EE9B77',
          '#EEC177',
          '#77A4EE',
          '#9AD3E5',
          '#BFD0E4'
        ]
      }
    }
  },
  data() {
    return {
      chart: null
    }
  },
  computed: {
    showChart: function () {
      return this.data === undefined || this.data.length > 0
    },
    series: function () {
      return [
        {
          type: 'pie',
          top: 10,
          right: 10,
          bottom: 10,
          left: 10,
          radius: [54, 65],
          center: ['22%', '50%'],
          label: {
            show: false
          },
          labelLine: {
            show: false
          },
          emphasis: {
            disabled: true,
            scale: false
          },
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 1
          },
          data: this.data.map((item) => {
            return {
              name: item.name || '',
              value: item.count
            }
          })
        }
      ]
    }
  },
  watch: {
    data() {
      this.updateChart()
    }
  },
  mounted() {
    this.initChart()
    this.updateChart()
    // 屏幕缩放的时候，重绘echart
    window.addEventListener('resize', this.resize, false)
  },
  beforeDestroy() {
    this.destroyChart()
    window.removeEventListener('resize', this.resize, false)
  },
  methods: {
    initChart() {
      if (this.chart || !Array.isArray(this.data) || this.data.length === 0) {
        return
      }

      this.chart = echarts.init(this.$refs.chart)
      return
    },
    resize() {
      if (this.$refs.chart) {
        const { width } = this.$refs.chart.getBoundingClientRect()
        this.chart?.setOption({
          legend: {
            textStyle: {
              rich: {
                a: {
                  width: width < 380 ? 80 : 100
                }
              }
            }
          }
        })
      }
      if (this.chart) {
        this.chart.resize()
      }
    },
    buildOption() {
      const { width } = this.$refs.chart.getBoundingClientRect()
      return {
        legend: {
          show: true,
          right: '16%',
          top: 'middle',
          height: 160,
          itemWidth: 0,
          itemHeight: 0,
          type: 'scroll',
          orient: 'vertical',
          selectedMode: false,
          pageIconSize: 10,
          formatter: (name) => {
            const itemIdx = this.data.findIndex((x) => x.name === name)
            const wordNum = Math.floor((width * 0.2) / 12) - 1
            let newName = name
            if (name.length > wordNum) {
              newName = name.substring(0, wordNum) + '...'
            }
            return (
              '{rect|}{a|' +
              addZero(itemIdx + 1) +
              '. ' +
              newName +
              '} {b| ' +
              this.data[itemIdx].value +
              '%}'
            ) // 使用 rect 标记 + 文本的方式来自定义 icon
          },
          // 自定义图例样式
          textStyle: {
            fontSize: 12,
            lineHeight: 18,
            fontWeight: 400,
            rich: {
              rect: {
                width: 12,
                height: 12,
                borderRadius: 2,
                backgroundColor: '{color| }'
              },
              a: {
                color: '#595959',
                padding: [0, 0, 0, 8],
                width: Math.floor(width * 0.2),
                fontFamily: 'PingFangSC-Regular, PingFang SC'
              },
              b: {
                color: '#262626',
                width: 50,
                align: 'right',
                fontFamily: 'ArialMT'
              }
            }
          }
        },
        color: this.colors,
        grid: {
          containLabel: true
        },
        tooltip: {
          show: true,
          extraCssText:
            'box-shadow: 0px 2px 10px 0px rgba(0,0,0,0.16);border-radius: 2px;border: 1px solid #D9D9D9;padding: 8px;',
          formatter: function (params) {
            const { color, name, value } = params
            const legendHtml = `<div class="series-item"><div class='marker' style="background-color:${color}"></div><div class="content-container"><div class="content-name">${name}</div><div class="content-value">${value.toLocaleString()}</div></div></div>`
            return legendHtml
          }
        },
        series: this.series
      }
    },
    destroyChart() {
      if (!this.chart) {
        return
      }

      this.chart.dispose()
      this.chart = null
    },
    updateChart() {
      if (!this.chart) {
        this.initChart()
      }

      if (this.chart) {
        this.chart.clear()
        const currentOptions = this.buildOption()
        this.chart.setOption(currentOptions)
      }
    }
  }
}
</script>

<style scoped lang="scss">
.pie-box {
  position: relative;
  width: 100%;
  height: 100%;
}

.inner-circle {
  position: absolute;
  left: calc(6px + 22%);
  top: 50%;
  transform: translate(-50%, -50%);
  width: 98px;
  height: 98px;
  border: 1px solid #f1f4fa;
  border-radius: 50%;
}

::v-deep {
  .series-item {
    display: flex;
    align-items: center;

    .marker {
      flex: 0 0 auto;
      margin-right: 8px;
      width: 8px;
      height: 8px;
      border-radius: 2px;
    }

    .content-container {
      font-size: 12px;
      font-family: PingFangSC-Regular, PingFang SC;
      line-height: 17px;
      flex: 1;
      width: 1%;

      .content-name {
        float: left;
        color: #5c5c5c;
        font-weight: 400;
        margin-right: 8px;
      }

      .content-value {
        float: right;
        font-family: PingFangSC-Medium, PingFang SC;
        font-weight: 500;
        color: #262626;
        margin-left: 8px;
      }
    }
  }
}
</style>
